import { defineStore } from 'pinia'
import axios from 'axios'
import { ElMessage } from 'element-plus'

// API配置
const API_BASE_URL = 'http://localhost:8081/api'

// 用于在拦截器中访问 store 和 router
let appStore = null
let appRouter = null

// 设置拦截器依赖（在 main.js 中调用）
export function setupInterceptors(store, router) {
  appStore = store
  appRouter = router
}

export const useAppStore = defineStore('app', {
  state: () => ({
    // 用户信息
    user: {
      id: null,
      token: '',
      tripStartDate: null,
      createTime: null
    },
    
    // 登录状态
    isLoggedIn: false,
    satoken: '',
    
    // 节假日数据 (按年份存储)
    holidayData: {},
    
    // 休息记录
    restRecords: [],
    
    // 统计数据
    statistics: {
      workDays: 0,
      restDays: 0,
      shouldRestDays: 0,
      owedRestDays: 0,
      travelDays: 0,
      totalDays: 0,
      periodStart: null,
      periodEnd: null
    },
    
    // 当前日历状态
    currentYear: new Date().getFullYear(),
    currentMonth: new Date().getMonth() + 1,
    includeTravel: false,
    
    // 未来日期选择限制
    futureSelectedDate: null
  }),
  
  actions: {
    // 登录
    async login(token) {
      try {
        const response = await axios.post(`${API_BASE_URL}/auth/login`, {
          token: token
        })
        
        if (response.data.code === 200) {
          this.user.token = token
          this.user.id = response.data.data.userId
          this.satoken = response.data.data.satoken
          this.isLoggedIn = true
          
          // 存储到localStorage
          localStorage.setItem('satoken', response.data.data.satoken)
          localStorage.setItem('userToken', token)
          localStorage.setItem('userId', response.data.data.userId)
          
          return response.data
        }
        throw new Error(response.data.message || '登录失败')
      } catch (error) {
        console.error('登录请求失败：', error)
        if (error.response && error.response.data) {
          throw new Error(error.response.data.message || '登录失败')
        }
        throw new Error('网络请求失败，请检查后端是否启动')
      }
    },
    
    // 登出
    async logout() {
      if (this.satoken) {
        try {
          await axios.post(`${API_BASE_URL}/auth/logout`, {}, {
            headers: {
              'satoken': this.satoken
            }
          })
          console.log('后端登出成功')
        } catch (error) {
          console.warn('后端登出失败，但仍清除前端状态：', error.message)
        }
      }
      
      // 清除前端状态
      this.user = {
        id: null,
        token: '',
        tripStartDate: null,
        createTime: null
      }
      this.isLoggedIn = false
      this.satoken = ''
      this.restRecords = []
      
      localStorage.removeItem('satoken')
      localStorage.removeItem('userToken')
      localStorage.removeItem('userId')
    },
    
    // 检查登录状态
    checkLoginStatus() {
      const satoken = localStorage.getItem('satoken')
      const userToken = localStorage.getItem('userToken')
      const userId = localStorage.getItem('userId')
      
      if (satoken && userToken) {
        this.satoken = satoken
        this.user.token = userToken
        this.user.id = userId ? parseInt(userId) : null
        this.isLoggedIn = true
        return true
      }
      return false
    },
    
    // 验证token有效性
    async validateToken() {
      if (!this.satoken) {
        return false
      }
      
      try {
        const response = await axios.get(`${API_BASE_URL}/auth/status`, {
          headers: {
            'satoken': this.satoken
          }
        })
        return response.data.code === 200 && response.data.data === true
      } catch (error) {
        // 区分401认证失败和其他错误
        if (error.response?.status === 401) {
          console.error('Token无效或已过期')
          return false
        }
        // 网络错误或服务器错误，返回true避免误判
        // 让后续的API请求来触发真正的错误处理
        console.warn('Token验证请求失败（可能是网络问题），暂时允许访问：', error.message)
        return true
      }
    },
    
    // 获取用户状态
    async getUserStatus() {
      try {
        const response = await axios.get(`${API_BASE_URL}/user/status`, {
          headers: {
            'satoken': this.satoken
          }
        })
        
        if (response.data.code === 200) {
          this.user.tripStartDate = response.data.data.tripStartDate
          this.restRecords = response.data.data.restRecords
          return response.data
        }
        throw new Error(response.data.message || '获取用户状态失败')
      } catch (error) {
        console.error('获取用户状态失败：', error)
        if (error.response && error.response.data) {
          throw new Error(error.response.data.message || '获取用户状态失败')
        }
        throw new Error('网络请求失败，请检查后端是否启动')
      }
    },
    
    // 获取节假日数据
    async getHolidayData(year) {
      // 只有当缓存中有数据（非空对象）时才使用缓存
      if (this.holidayData[year] && Object.keys(this.holidayData[year]).length > 0) {
        return { code: 200, data: this.holidayData[year], hasData: true }
      }
      
      try {
        const response = await axios.get(`${API_BASE_URL}/holidays/${year}`, {
          headers: {
            'satoken': this.satoken
          }
        })
        
        if (response.data.code === 200) {
          // 将数组格式转换为按MM-dd为key的对象格式
          const holidayArray = response.data.data
          const holidayMap = {}
          
          holidayArray.forEach(holiday => {
            // 从YYYY-MM-DD格式提取MM-DD
            const monthDay = holiday.date.substring(5) // 提取"MM-DD"部分
            holidayMap[monthDay] = {
              name: holiday.name,
              isHoliday: holiday.isHoliday,
              date: holiday.date
            }
          })
          
          // 只有当获取到数据时才缓存
          if (Object.keys(holidayMap).length > 0) {
            this.holidayData[year] = holidayMap
            return { ...response.data, hasData: true }
          } else {
            // 返回空数据标记，提示用户暂无该年份数据
            console.warn(`${year}年暂无节假日数据`)
            return { ...response.data, hasData: false, emptyYear: year }
          }
        }
        throw new Error(response.data.message || '获取节假日数据失败')
      } catch (error) {
        console.error('获取节假日数据失败：', error)
        if (error.response && error.response.data) {
          throw new Error(error.response.data.message || '获取节假日数据失败')
        }
        throw new Error('网络请求失败，请检查后端是否启动')
      }
    },
    
    // 设置出差开始日期
    async setTripStartDate(startDate) {
      try {
        const response = await axios.post(`${API_BASE_URL}/user/trip-start`, {
          startDate: startDate
        }, {
          headers: {
            'satoken': this.satoken
          }
        })
        
        if (response.data.code === 200) {
          this.user.tripStartDate = startDate
          return response.data
        }
        throw new Error(response.data.message || '设置出差开始日期失败')
      } catch (error) {
        console.error('设置出差开始日期失败：', error)
        if (error.response && error.response.data) {
          throw new Error(error.response.data.message || '设置出差开始日期失败')
        }
        throw new Error('网络请求失败，请检查后端是否启动')
      }
    },
    
    // 添加休息记录
    async addRestRecord(record) {
      try {
        const response = await axios.post(`${API_BASE_URL}/rest`, record, {
          headers: {
            'satoken': this.satoken
          }
        })
        
        if (response.data.code === 200) {
          // 添加到本地状态
          this.restRecords.push(response.data.data)
          return response.data
        }
        throw new Error(response.data.message || '添加休息记录失败')
      } catch (error) {
        console.error('添加休息记录失败：', error)
        if (error.response && error.response.data) {
          throw new Error(error.response.data.message || '添加休息记录失败')
        }
        throw new Error('网络请求失败，请检查后端是否启动')
      }
    },
    
    // 更新休息记录
    async updateRestRecord(id, record) {
      try {
        const response = await axios.put(`${API_BASE_URL}/rest/${id}`, record, {
          headers: {
            'satoken': this.satoken
          }
        })
        
        if (response.data.code === 200) {
          // 更新本地状态
          const index = this.restRecords.findIndex(r => r.id === id)
          if (index !== -1) {
            this.restRecords[index] = response.data.data
          }
          return response.data
        }
        throw new Error(response.data.message || '更新休息记录失败')
      } catch (error) {
        console.error('更新休息记录失败：', error)
        if (error.response && error.response.data) {
          throw new Error(error.response.data.message || '更新休息记录失败')
        }
        throw new Error('网络请求失败，请检查后端是否启动')
      }
    },
    
    // 删除休息记录
    async deleteRestRecord(id) {
      try {
        const response = await axios.delete(`${API_BASE_URL}/rest/${id}`, {
          headers: {
            'satoken': this.satoken
          }
        })
        
        if (response.data.code === 200) {
          // 从本地状态移除
          const index = this.restRecords.findIndex(r => r.id === id)
          if (index !== -1) {
            this.restRecords.splice(index, 1)
          }
          return response.data
        }
        throw new Error(response.data.message || '删除休息记录失败')
      } catch (error) {
        console.error('删除休息记录失败：', error)
        if (error.response && error.response.data) {
          throw new Error(error.response.data.message || '删除休息记录失败')
        }
        throw new Error('网络请求失败，请检查后端是否启动')
      }
    },
    
    // 获取统计数据
    async getStatistics(params = {}) {
      try {
        let response
        
        // 如果没有提供参数，使用默认统计接口
        if (!params.startDate && !params.endDate) {
          response = await axios.get(`${API_BASE_URL}/statistics/default`, {
            params: {
              includeTravel: params.includeTravel || false
            },
            headers: {
              'satoken': this.satoken
            }
          })
        } else {
          // 使用自定义时间范围统计接口
          response = await axios.post(`${API_BASE_URL}/statistics`, {
            startDate: params.startDate,
            endDate: params.endDate,
            includeTravel: params.includeTravel || false
          }, {
            headers: {
              'satoken': this.satoken
            }
          })
        }
        
        if (response.data.code === 200) {
          this.statistics = {
            workDays: response.data.data.workDays,
            restDays: response.data.data.actualRestDays,
            shouldRestDays: response.data.data.shouldRestDays,
            owedRestDays: response.data.data.owedRestDays,
            travelDays: response.data.data.travelDays,
            totalDays: response.data.data.totalDays,
            periodStart: response.data.data.startDate,
            periodEnd: response.data.data.endDate
          }
          return response.data
        }
        throw new Error(response.data.message || '获取统计数据失败')
      } catch (error) {
        console.error('获取统计数据失败：', error)
        if (error.response && error.response.data) {
          throw new Error(error.response.data.message || '获取统计数据失败')
        }
        throw new Error('网络请求失败，请检查后端是否启动')
      }
    },
    
    // 休息记录分析和验证函数
    
    // 获取排序后的休息记录
    getSortedRestRecords() {
      return [...this.restRecords].sort((a, b) => new Date(a.startDate) - new Date(b.startDate))
    },
    
    // 验证日期间隔（至少1天工作时间）
    validateDateInterval(date1, date2) {
      const d1 = new Date(date1)
      const d2 = new Date(date2)
      const diffTime = Math.abs(d2 - d1)
      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
      return diffDays >= 2 // 至少间隔1天
    },
    
    // 检查日期是否与现有休息记录冲突
    checkDateConflict(startDate, endDate, excludeId = null) {
      const records = this.restRecords.filter(r => r.id !== excludeId)
      
      for (const record of records) {
        const recordStart = new Date(record.startDate)
        const recordEnd = record.endDate ? new Date(record.endDate) : new Date()
        const checkStart = new Date(startDate)
        const checkEnd = endDate ? new Date(endDate) : new Date()
        
        // 检查是否重叠
        if (checkStart <= recordEnd && checkEnd >= recordStart) {
          return record
        }
      }
      return null
    },
    
    // 分析点击日期的可用操作
    analyzeClickOptions(clickDate) {
      const today = new Date().toISOString().split('T')[0]
      const sortedRecords = this.getSortedRestRecords()
      
      // 检查是否是未来日期
      const isFuture = clickDate > today
      if (isFuture && this.futureSelectedDate && this.futureSelectedDate !== clickDate) {
        return [] // 已有未来选择，不能再选择其他未来日期
      }
      
      // 找到点击日期在休息记录中的位置
      let position = 'before_all'
      let prevRecord = null
      let nextRecord = null
      let conflictRecord = null // 记录与哪个记录有冲突
      
      for (let i = 0; i < sortedRecords.length; i++) {
        const record = sortedRecords[i]
        const recordStart = new Date(record.startDate)
        const clickDateObj = new Date(clickDate)
        
        if (clickDateObj < recordStart) {
          nextRecord = record
          if (i === 0) {
            position = 'before_all'
          } else {
            position = 'between'
            prevRecord = sortedRecords[i - 1]
          }
          break
        } else if (record.endDate) {
          // 只有有明确结束日期的记录才判断是否在记录内
          const recordEnd = new Date(record.endDate)
          if (clickDateObj >= recordStart && clickDateObj <= recordEnd) {
            position = 'within'
            prevRecord = record
            break
          }
        } else {
          // 对于进行中的休息记录，只有开始日期匹配才算在记录内
          if (clickDate === record.startDate) {
            position = 'within'
            prevRecord = record
            break
          }
        }
        
        if (i === sortedRecords.length - 1) {
          position = 'after_all'
          prevRecord = record
        }
      }
      
      // 检查间隔冲突
      if (prevRecord && prevRecord.endDate) {
        // 只对有明确结束日期的记录检查间隔冲突
        if (!this.validateDateInterval(prevRecord.endDate, clickDate)) {
          conflictRecord = prevRecord
        }
      }
      // 对于进行中的休息记录，不检查间隔冲突，用户可以随时结束当前休息
      
      if (nextRecord && !conflictRecord) {
        if (!this.validateDateInterval(clickDate, nextRecord.startDate)) {
          conflictRecord = nextRecord
        }
      }
      
      // 根据位置和冲突情况生成选项
      return this.generateOptionsForPosition(position, clickDate, prevRecord, nextRecord, isFuture, conflictRecord, sortedRecords)
    },
    
    // 根据位置生成操作选项
    generateOptionsForPosition(position, clickDate, prevRecord, nextRecord, isFuture, conflictRecord, sortedRecords) {
      const options = []
      
      // 如果有间隔冲突，只提供修改选项
      if (conflictRecord) {
        return this.generateConflictOptions(clickDate, conflictRecord)
      }
      
      switch (position) {
        case 'before_all':
          // 如果没有任何休息记录，优先显示开始休息
          if (sortedRecords.length === 0) {
            options.push({
              type: 'new_rest_start',
              startDate: clickDate,
              label: `开始休息`,
              description: `从${clickDate}开始休息`,
              priority: 'high'
            })
          } else {
            // 有记录时，优先显示设为结束日期
            options.push({
              type: 'new_rest_end',
              endDate: clickDate,
              label: `设为休息结束日期`,
              description: `需要选择对应的休息开始日期`,
              priority: 'high'
            })
            
            // 修改操作（不明显）
            if (nextRecord) {
              options.push({
                type: 'modify_start',
                target: nextRecord,
                newDate: clickDate,
                label: `修改休息开始日期`,
                description: `将${nextRecord.startDate}开始的休息修改为${clickDate}开始`,
                priority: 'low'
              })
            }
          }
          break
          
        case 'between':
          // 检查是否可以在此日期开始新的休息
          if (this.canStartRestAt(clickDate)) {
            options.push({
              type: 'new_rest_start',
              startDate: clickDate,
              label: `开始新的休息`,
              description: `从${clickDate}开始休息，需选择结束日期`,
              priority: 'high'
            })
          }
          
          // 检查是否可以在此日期结束休息
          if (this.canEndRestAt(clickDate)) {
            options.push({
              type: 'new_rest_end',
              endDate: clickDate,
              label: `设为休息结束日期`,
              description: `在${clickDate}结束休息，需选择开始日期`,
              priority: 'high'
            })
          }
          
          // 修改操作（不明显）
          if (prevRecord) {
            options.push({
              type: 'modify_end',
              target: prevRecord,
              newDate: clickDate,
              label: `延长上次休息`,
              description: `将上次休息延长到${clickDate}`,
              priority: 'low'
            })
          }
          
          if (nextRecord) {
            options.push({
              type: 'modify_start',
              target: nextRecord,
              newDate: clickDate,
              label: `提前下次休息`,
              description: `将下次休息提前到${clickDate}开始`,
              priority: 'low'
            })
          }
          break
          
        case 'after_all':
          // 检查最后一条记录是否是进行中的休息
          if (prevRecord && !prevRecord.endDate) {
            // 如果最后一条记录是进行中的休息，优先显示结束当前休息
            options.push({
              type: 'end_current_rest',
              target: prevRecord,
              newDate: clickDate,
              label: `结束当前休息`,
              description: `在${clickDate}结束当前休息`,
              priority: 'high'
            })
            
            // 延长休息选项（低优先级）
            options.push({
              type: 'modify_end',
              target: prevRecord,
              newDate: clickDate,
              label: `延长当前休息`,
              description: `将当前休息延长到${clickDate}`,
              priority: 'low'
            })
          } else {
            // 如果没有进行中的休息，显示新增操作
            options.push({
              type: 'new_rest_start',
              startDate: clickDate,
              label: `开始新的休息`,
              description: isFuture ? `预设${clickDate}开始休息` : `从${clickDate}开始休息`,
              priority: 'high'
            })
            
            // 修改上次休息结束日期（低优先级）
            if (prevRecord) {
              options.push({
                type: 'modify_end',
                target: prevRecord,
                newDate: clickDate,
                label: `延长最后休息`,
                description: `将最后一次休息延长到${clickDate}`,
                priority: 'low'
              })
            }
          }
          break
          
        case 'within':
          // 在休息期间内，优先显示结束当前休息
          if (prevRecord && !prevRecord.endDate) {
            options.push({
              type: 'end_current_rest',
              target: prevRecord,
              newDate: clickDate,
              label: `结束当前休息`,
              description: `在${clickDate}结束当前休息`,
              priority: 'high'
            })
          }
          
          // 修改操作（不明显）
          if (prevRecord) {
            if (prevRecord.endDate) {
              options.push({
                type: 'modify_start',
                target: prevRecord,
                newDate: clickDate,
                label: `调整开始日期`,
                description: `调整为${clickDate}开始`,
                priority: 'low'
              })
              
              options.push({
                type: 'modify_end',
                target: prevRecord,
                newDate: clickDate,
                label: `调整结束日期`,
                description: `调整为${clickDate}结束`,
                priority: 'low'
              })
            }
          }
          break
      }
      
      // 按优先级排序，高优先级在前
      return options.sort((a, b) => {
        const priorityOrder = { 'high': 0, 'medium': 1, 'low': 2 }
        return priorityOrder[a.priority || 'medium'] - priorityOrder[b.priority || 'medium']
      })
    },
    
    // 生成冲突情况下的选项
    generateConflictOptions(clickDate, conflictRecord) {
      const options = []
      const today = new Date().toISOString().split('T')[0]
      
      // 判断冲突记录在点击日期的前面还是后面
      if (clickDate < conflictRecord.startDate) {
        // 点击日期在冲突记录之前，可以修改冲突记录的开始日期
        options.push({
          type: 'modify_start',
          target: conflictRecord,
          newDate: clickDate,
          label: `将休息开始日期提前到${clickDate}`,
          description: `将${conflictRecord.startDate}${conflictRecord.endDate ? '-' + conflictRecord.endDate : '-进行中'}的开始日期修改为${clickDate}`,
          priority: 'high'
        })
      } else {
        // 点击日期在冲突记录之后，可以修改冲突记录的结束日期
        const effectiveEndDate = conflictRecord.endDate || today
        options.push({
          type: 'modify_end',
          target: conflictRecord,
          newDate: clickDate,
          label: `将休息结束日期延后到${clickDate}`,
          description: `将${conflictRecord.startDate}-${effectiveEndDate}的结束日期修改为${clickDate}`,
          priority: 'high'
        })
      }
      
      return options
    },
    
    // 检查是否可以在指定日期开始休息
    canStartRestAt(clickDate) {
      const sortedRecords = this.getSortedRestRecords()
      const today = new Date().toISOString().split('T')[0]
      
      // 找到点击日期后的第一个休息记录
      let nextRecord = null
      for (const record of sortedRecords) {
        if (record.startDate > clickDate) {
          nextRecord = record
          break
        }
      }
      
      if (nextRecord) {
        // 计算可用的结束日期范围
        // 结束日期最早可以等于开始日期（当天开始当天结束）
        const minEndDate = clickDate
        
        const nextStartDate = new Date(nextRecord.startDate)
        nextStartDate.setDate(nextStartDate.getDate() - 2) // 保证至少1天工作间隔
        const maxEndDate = nextStartDate.toISOString().split('T')[0]
        
        // 检查是否有有效的结束日期范围
        return minEndDate <= maxEndDate
      }
      
      // 如果后面没有休息记录，可以开始
      return true
    },
    
    // 检查是否可以在指定日期结束休息
    canEndRestAt(clickDate) {
      const sortedRecords = this.getSortedRestRecords()
      
      // 找到点击日期前的最后一个休息记录
      let prevRecord = null
      for (let i = sortedRecords.length - 1; i >= 0; i--) {
        const record = sortedRecords[i]
        const recordEnd = record.endDate || new Date().toISOString().split('T')[0]
        if (recordEnd < clickDate) {
          prevRecord = record
          break
        }
      }
      
      if (prevRecord) {
        // 计算可用的开始日期范围
        const prevEndDate = new Date(prevRecord.endDate || prevRecord.startDate)
        prevEndDate.setDate(prevEndDate.getDate() + 2) // 保证至少1天工作间隔
        const minStartDate = prevEndDate.toISOString().split('T')[0]
        
        // 开始日期最晚可以等于结束日期（当天开始当天结束）
        const maxStartDate = clickDate
        
        // 检查是否有有效的开始日期范围
        return minStartDate <= maxStartDate
      }
      
      // 如果前面没有休息记录，可以结束
      return true
    }
  }
})

// 防止重复处理401错误的标志
let isHandling401 = false

// Axios 响应拦截器：处理 401 未授权错误
axios.interceptors.response.use(
  response => response,
  error => {
    // 处理 401 未授权错误（添加防抖机制）
    if (error.response?.status === 401 && !isHandling401) {
      isHandling401 = true
      
      // 清除登录状态
      if (appStore) {
        appStore.logout()
      }
      
      // 跳转到登录页
      if (appRouter) {
        appRouter.push('/login')
      }
      
      // 显示错误提示
      ElMessage.error('登录已过期，请重新登录')
      
      // 1秒后重置标志，防止短时间内重复触发
      setTimeout(() => {
        isHandling401 = false
      }, 1000)
    }
    return Promise.reject(error)
  }
)
